﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
//using WordSmith_V1.UI.Models;
using System.Web.Security;
using WordSmith_V1.ViewModel;
//using WordSmith_V1.BusinessLogic;
using WordSmith_V1.Library;
using System.Text;
using WordSmith_V1.Library.Model;
using WordSmith_V1.Library.Model.EntityFrameWork;
//using WordSmith_V1.Library.Services;
using WordSmith_V1.Library.Security;
using WordSmiths_V1.UI.Models;

namespace WordSmith_V1.Controllers
{ 
   // [Authorize] //this denies authorize access to every controller action.
    public class UserController : Controller
    {
        private WordSmithContext DB = new WordSmithContext();
        private readonly IUserService _userService;
         

       /* public UserController(IUserService userService)
        {
            _userService = userService;
        }
        */
        //
        // GET: /User/

        public ViewResult Index()
        {
            string username = "Hi";
            if (Request.IsAuthenticated)
            {
                username = User.Identity.Name;
                FormsIdentity ident = (FormsIdentity)User.Identity;
                if (ident != null)
                {
                    username = string.Format("Welcome, {0} ", ident.Name);
                }
            }
            ViewBag.message = username;
            UserHomePageViewModel viewModel = new UserHomePageViewModel();
            List<Menu> menuLinks = new List<Menu>{ new Menu("Info","Info","User"),new Menu("Book Followed","BookFollowed","Book"),new Menu("Multimedia","Multimedia","User"),new Menu("Start a book","Create","Book")
               };
            viewModel.userMenuLinks = menuLinks;
            return View(viewModel); //return a new UserHomePageViewModel
        }

        public ActionResult Summary()
        {
            AccountSummaryViewModel viewModel = new AccountSummaryViewModel();
            if (Request.IsAuthenticated)
            {
                FormsIdentity ident = (FormsIdentity)User.Identity;
                if (ident != null)
                {
                    var user = DB.Users.Where(c => c.Email == ident.Name).Include(g => g.BookFollowed)
                        .Take(1)
                        .ToList()
                        .FirstOrDefault();
                    viewModel.User = user;
                }
            }
            //ViewBag.message = username;

            List<Menu> menuLinks = new List<Menu>{ new Menu("Home","Home","Home"),new Menu("News","News","News"),new Menu("Members","Members","Members"),
                new Menu("Forums","Forums","Forums"),
                new Menu("Feedback","Feedback","Feedback"),
                new Menu("Bookstore","Bookstore","Bookstore"),new Menu("Sign out","SignOut","User")};
            viewModel.userMenuLinks = menuLinks;
            
            return View(viewModel); 
        }

        public ActionResult Login()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Summary(AccountSummaryViewModel viewModel)
        {
            return RedirectToAction("Index");
        }

        public ActionResult StartABook()
        {
            if (Request.IsAuthenticated)
            {

            }
            return RedirectToAction("Create", "Book");
        }
        //
        // GET: /User/Create

      //  public ActionResult Create()
     //   {
          //  ViewBag.Rankid = new SelectList(DB.URanks, "id", "name");
      //      return View();
      //  }

       // TODO: [Action]
        public  ActionResult SignOut()
        {
            FormsAuthentication.SignOut();
            //Session["DashUser"] = null;
            //return RedirectToAction("Index");
            return RedirectToActionPermanent("Index", "Home");
        }
        //
        // POST: /User/Create
        [HttpPost]
        public ActionResult Login(AccountViewModel accountViewModel, string returnUrl)
        {
          //  if (!ModelState.IsValid)
          //  {
          //      return View("Index");
          //  }
            var user = DB.Users
               .Where(c => c.Email == accountViewModel.Email)
               .Take(1)
               .ToList()
               .FirstOrDefault();
            UserService userService = new UserService();
            if (user == null || !userService.CheckUserCredentials(DB, accountViewModel.Email, accountViewModel.Password))
            {
                
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
                return View(accountViewModel);
            }

            AuthenticateUser(user);

            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            return RedirectToAction("Index");//RedirectToAction("Index", "Home");
        }

        private void AuthenticateUser(User user)
        {
            FormsAuthentication.Initialize();
            var ticket = new FormsAuthenticationTicket(1, user.Email, DateTime.UtcNow,
                                                                             DateTime.UtcNow.AddMinutes(90), true,
                                                                             user.FirstName, //TODO: change
                                                                             FormsAuthentication.FormsCookiePath);
            var hash = FormsAuthentication.Encrypt(ticket);
            Response.Cookies.Clear();
            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);
            if (!ticket.IsPersistent) return;
            cookie.Expires = ticket.Expiration;
            Response.Cookies.Add(cookie);
        }

        [HttpPost]
        public ActionResult Create(AccountViewModel accountViewModel)
        {
            if (ModelState.IsValid)
            {
                var checkUserExist = DB.Users.Where(user => user.Email == accountViewModel.Email)
                                                    .Take(1)
                                                    .ToList()
                                                    .FirstOrDefault();

                if (checkUserExist == null)
                {
                    string salt = "";
                    string encryptedHash = Encryption.Encrypt(accountViewModel.Password,ref salt);
                    Credential credential = new Credential(accountViewModel.Email, encryptedHash);
                    credential.Salt = Encryption.GetBytes(salt);
                    DB.Credentials.Add(credential);
                    DB.SaveChanges();
                   int newId =  credential.Id;
                   // entity framework return id after insert

                    //create new user from register model data
                    User newUser = new User();
                    newUser.Email = accountViewModel.Email;
                    newUser.FirstName = accountViewModel.FirstName;
                    newUser.LastName = accountViewModel.LastName;
                    newUser.Username = string.Format("{0} {1}", accountViewModel.FirstName, accountViewModel.LastName);
                    newUser.CredentialId = newId;
                    DB.Users.Add(newUser);
                    DB.SaveChanges();

                    accountViewModel.User = newUser;
                    accountViewModel.User.UpdateCredentials(credential, accountViewModel.Email);
                    AuthenticateUser(accountViewModel.User);
                    return RedirectToAction("Create2");
                }
                else
                {
                    ModelState.AddModelError("Email", "This email is already registered");
                    return View("Create");
                }
            }
            else
           {
                return View("Create");
            }
            
        }


        //
        // POST: /User/Create

       // [HttpPost]
        public ActionResult Create2(Register Users)
        {
         //TO DO SELECT ALL:  DB.Genres
            var genres = DB.Genres.OrderByDescending(g => g.Name);
            UserInterestViewModel interestsView = new UserInterestViewModel();
            /*List<string> genres = new List<string>{"action","adult","adventure","anger","angst",
"animals","art","beauty" ,"betrayal","blog","blood","book","books","cats","childhood","children","christian","christianity",
"christmas","comedy","coming-of-age","contemporary","contemporary-romance","crime (289)"};*/
            foreach(var i in genres)
            {                
                interestsView.UserInterests.Add(new InterestViewModel
                {
                    Interested = false,
                    InterestId = i.Id,
                    Name =  i.Name
                });
            }
            return View(interestsView);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create2(FormCollection formCollection)
        {

            var genres = DB.Genres.OrderByDescending(g => g.Name);
            List<Genre> selectedGenres = new List<Genre>();           
            //get genres in the DB
            //for each of them 
            //do a check if their checkbox is clicked
            //if yes, add Genre to List ot user interests
            bool isChecked;
            int i = 0;
            foreach (var genre in genres)
            {
                Boolean.TryParse(Request.Form.GetValues("UserInterests[" + i + "].Interested")[0], out isChecked);
                if (isChecked)
                {
                    selectedGenres.Add(genre);
                }
                i++;
            }

            User currentUser = new User();
            FormsIdentity ident = (FormsIdentity)User.Identity;
            if (ident != null)
            {
                var userEntity = DB.Users.Where(u => u.Email == ident.Name).Take(1)
               .ToList()
               .FirstOrDefault();
                userEntity.Interests = selectedGenres;
                DB.SaveChanges();
            }
            return RedirectToAction("FollowBooks");
        }

        public ActionResult FollowBooks()
        {
            //build a complex relationship beween books and Genre
             if (Request.IsAuthenticated)
            {
                FormsIdentity ident = (FormsIdentity)User.Identity;
                if (ident != null)
                {
                    var user = DB.Users.Where(c => c.Email == ident.Name).Include(intrs => intrs.Interests)
                        .Take(1)
                        .ToList()
                            .FirstOrDefault();

                    
                    List<Book> books = new List<Book>();
                    foreach (var userInt in user.Interests)
                    {
                        var booksWithInterest = DB.Books.Where(bk => bk.GenreId == userInt.Id);
                        books.AddRange(booksWithInterest);
                    }

                    UserFollowBooksViewModel viewModel = new UserFollowBooksViewModel();
                    viewModel.Books = books;
                    return View(viewModel);
                }
                 
            }
            return Index();
        }




        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult FollowBooks(FormCollection formCollection)
        {

            var books = DB.Books.OrderByDescending(g => g.Title);
            List<Book> booksFollowed = new List<Book>();          
            //get genres in the DB
            //for each of them 
            //do a check if their checkbox is clicked
            //if yes, add Genre to List ot user interests
            bool isChecked;
            int i = 0;
            try
            {
                foreach (var book in books)
                {
                    Boolean.TryParse(Request.Form.GetValues("FollowBooks[" + i + "].Interested")[0], out isChecked);
                    if (isChecked)
                    {
                        booksFollowed.Add(book);
                    }
                    i++;
                }

                User currentUser = new User();
                FormsIdentity ident = (FormsIdentity)User.Identity;
                if (booksFollowed.Count != 0 && ident != null)
                {
                    var userEntity = DB.Users.Where(u => u.Email == ident.Name).Take(1)
                   .ToList()
                   .FirstOrDefault();
                    userEntity.BookFollowed = booksFollowed;
                    DB.SaveChanges();
                }
                return RedirectToAction("Create3");
            }
            catch
            {
                return RedirectToAction("Create3");
            }
        }


        
        public ActionResult Create3()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create3(FormCollection formCollection)
        {
            //Call External Contacts-Importing API

            //TODO: add addition param to for the new User credentials
            return RedirectToAction("Index", "Home");
        }
        public ActionResult AddGoogleContacts(FormCollection formcollection)
        {
            //Google: https://developers.google.com/google-apps/contacts/v3/
           // GoogleContacts.retrieveContact();
            return View();
        }

      
        //
        // GET: /User/Edit/5
 /*
        public ActionResult Edit(string id)
        {
            Users Users = DB.Users.Find(id);
            ViewBag.Rankid = new SelectList(DB.URanks, "id", "name", Users.Rankid);
            return View(Users);
        }

        //
        // POST: /User/Edit/5

        [HttpPost]
        public ActionResult Edit(Users Users)
        {
            if (ModelState.IsValid)
            {
                DB.Entry(Users).State = EntityState.Modified;
                DB.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.Rankid = new SelectList(DB.URanks, "id", "name", Users.Rankid);
            return View(Users);
        }
        */
        //
        // GET: /User/Delete/5
 /*
        public ActionResult Delete(string id)
        {
            Users Users = DB.Users.Find(id);
            return View(Users);
        }

        //
        // POST: /User/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(string id)
        {            
            Users Users = DB.Users.Find(id);
            DB.Users.Remove(Users);
            DB.SaveChanges();
            return RedirectToAction("Index");
        }
        */
        protected override void Dispose(bool disposing)
        {
            DB.Dispose();
            base.Dispose(disposing);
        }

      /*  [HttpPost]
        public ActionResult Login(FormCollection model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
               // Users user = DB.Users.FirstOrDefault(u => u.Email == model.Email);
                /*
                if (user == null)
                {
                    ModelState.AddModelError("", "No user found");
                    return View(model);
                }

                if (Encryption.CheckHash(model.EncryptedHash, user.EncryptedHash))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, false);
                    return RedirectToAction("Summary", "AdminConsole");
                }*/
         //   }
            // If we got this far, something failed, redisplay form
           /* ModelState.AddModelError("", "The user name or password provided is incorrect.");
            return View(model);
        }*/
    }
}